Introduction

The HTTP Host header is a mandatory header for HTTP requests and specifies the domain name which the client wants to access. This is especially handy with virtual hosting because a single IP address may provide different services on different domains and the server needs to know which page to return to the client. For example, the same machine may serve a blog website at blog.example.com and a git repository at dev.example.com.

In order to specify which of the two services the client wants to access, they must specify either the header Host: blog.example.com or dev.example.com, respectively, in their request.

A host header injection vulnerability arises when the target application unsafely uses the contents of the Host header, typically in order to construct an absolute URL.

Password Reset Poisoning

This technique involves using Host Header Injection in order to force a vulnerable application to generate a password reset link which points to a malicious domain. This may be leveraged to steal the secret tokens required to reset the passwords of arbitrary users and consequently compromise their accounts.

Typically applications implement password resetting as follows.

  1. The user specifies their username/email.
  2. The server generates a temporary, unique, high-entropy token for the user.
  3. The server generates a URL for the password reset with the secret token included as a URL parameter. For example, example.com/reset?token=abcdefghijklmnopqrstuvwxyz
  4. The server sends an email to the client which includes the generated password reset link.
  5. When the user clicks the link in their email, the token in the URL is used by server in order to determine whose password is being reset and whether or not it is a valid request.

If the Host header of the request for a password reset is used in generating the password reset URL, an adversary may leverage it in order to steal the token for an arbitrary user. For example, an adversary could submit a password reset request for a user, e.g. carlos, intercept the request and modify the Host header to point to a domain controlled by them: Host: exploit-server.com.

When the server generates the password reset URL, it will resemble the following, http://exploit-server.com/reset?token=abcdefghijklmnopqrstuvwxyz. If the victim clicks on the link, their token will be handed over to the attacker by means of the exploit-server.com domain which receives the password reset request.

This type of attack, however, does not always require user interaction because emails are typically scanned be it to determine if they are spam or if they contain a virus and the scanners will oftentimes open the links themselves, all automatically, thus giving the attacker the token to reset the password.

Prevention

  1. Check to see if absolute URLs are necessary and cannot be replaced with relative ones.
  2. If an absolute URL is necessary, ensure that the current domain is stored in a configuration file and do NOT use the one from the Host: header.
  3. If using the Host header is inevitable, ensure that it is validated against a whitelist of permitted domains. Different frameworks may provide different methods for achieving this.
  4. Drop support for additional headers which may permit such attacks, such as the X-Forward-Host header.
  5. Do NOT virtual-host internal-only websites on a server which also provides public-facing content, since those may be accessed via manipulation of the Host header.